package liuyang.bigeventserver.modules.security.handler.exception;

import com.fasterxml.jackson.databind.ObjectMapper;
import liuyang.bigeventserver.common.R;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

/**
 * 认证异常处理 e.g. 访问了没有权限的受保护资源
 * 会被过滤器链中的ExceptionTranslationFilter调用
 *
 * @author liuyang
 * @since 2022/3/28
 *        2024/2/27 更换为jakarta包,并组件化@Component
 *        2024/2/28 废弃RespHelper
 */
@Component
@Slf4j
@AllArgsConstructor
public class RespJsonAccessDeniedHandler implements AccessDeniedHandler {

    private final ObjectMapper om;

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        log.error(accessDeniedException.getMessage(), accessDeniedException);

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Cache-Control", "no-cache");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");

        // need JDK 11
        Map<String, Object> msg = Map.of(
                "msg", "无权访问该资源(权限不足)",
                "details", accessDeniedException.getMessage());
        response.getWriter().println(om.writeValueAsString(R.error().put("data", msg)));
    }
}
